#ifndef _POLYNOMIAL_H_
#define _POLYNOMIAL_H_



#include<iostream>
#include<vector>
#include<cmath>
#include "Vec.h"

using namespace std;


template<int Order,class CoefType>
class Polynomial
{
private:
  int d;                         
  /** Order  */  
  vector<CoefType> Coef;
  /** the coefficients of the polynomial,
      from low-order item to high-order item,
      which has d numbers */
  
public:
  Polynomial(){};
  Polynomial(vector<CoefType> arr);
  template<int Ord1>
  Polynomial& operator=(const Polynomial<Ord1,CoefType> &p);
  template<int Ord1,int Ord2,class Type>	
  friend Polynomial<(Ord1>=Ord2)?Ord1:Ord2,Type> operator+(const Polynomial<Ord1,Type> &p1,const Polynomial<Ord2,Type> &p2);
  template<int Ord1,int Ord2,class Type> 
  friend Polynomial<(Ord1>=Ord2)?Ord1:Ord2,Type> operator-(const Polynomial<Ord1,Type> &p1,const Polynomial<Ord2,Type> &p2);
  template<int Ord1,int Ord2,class Type> 
  friend Polynomial<Ord1+Ord2-1,Type> operator*(const Polynomial<Ord1,Type> &p1,const Polynomial<Ord2,Type> &p2);
  template<int Ord,class Type> friend Polynomial<Ord,Type> operator*(Type c,const Polynomial<Ord,Type> &p);
	template<int Ord,class Type> friend Polynomial<Ord,Type> operator+(Type c,const Polynomial<Ord,Type> &p);	
  template<int Ord,class Type> friend ostream& operator<<(ostream& os,const Polynomial<Ord,Type> &p); 
	void print()const;
	/**  output the polynomial for the CoefType=Vec<double,dim> and alike*/
  CoefType get_value(double x)const;
  /** return evaluation at some x  */
  Polynomial get_deri()const;
  /** return derivative of the polynomial */
  CoefType get_deri_value(double x)const;
  /** return the value of derivative at some x */
  vector<CoefType> get_Coef()const;
  /** return coefficients */
  ~Polynomial(){};
};


#endif
